/**
 * Copyright &copy; 2012-2013 All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.neusoft.lohas.modules.ivm.utils;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neusoft.lohas.common.service.BaseService;
import com.neusoft.lohas.common.utils.SpringContextHolder;
import com.neusoft.lohas.modules.ivm.dao.merchant.DeliveryMemberDao;
import com.neusoft.lohas.modules.ivm.dao.merchant.ReceiptTimeDao;
import com.neusoft.lohas.modules.ivm.dao.product.ProductClassifyDao;
import com.neusoft.lohas.modules.ivm.dao.product.ProductDao;
import com.neusoft.lohas.modules.ivm.dao.product.ProductUnitDao;
import com.neusoft.lohas.modules.ivm.dao.product.SupplierDao;
import com.neusoft.lohas.modules.ivm.entity.merchant.DeliveryMember;
import com.neusoft.lohas.modules.ivm.entity.merchant.ReceiptTime;
import com.neusoft.lohas.modules.ivm.entity.merchant.TimeSlot;
import com.neusoft.lohas.modules.ivm.entity.product.Product;
import com.neusoft.lohas.modules.ivm.entity.product.ProductClassify;
import com.neusoft.lohas.modules.ivm.entity.product.ProductUnit;
import com.neusoft.lohas.modules.ivm.entity.product.Supplier;
import com.neusoft.lohas.modules.sys.security.SystemAuthorizingRealm.Principal;

/**
 * 商品工具类
 * @author jackie.liu
 * @version 2014-11-13
 */
public class ProductUtils extends BaseService {

	private static ProductDao productDao = SpringContextHolder.getBean(ProductDao.class);
	private static ProductClassifyDao productClassifyDao = SpringContextHolder.getBean(ProductClassifyDao.class);
	private static ProductUnitDao productUnitDao = SpringContextHolder.getBean(ProductUnitDao.class);
	private static DeliveryMemberDao memberDao = SpringContextHolder.getBean(DeliveryMemberDao.class);
	private static SupplierDao supplierDao = SpringContextHolder.getBean(SupplierDao.class);
	private static ReceiptTimeDao timeDao = SpringContextHolder.getBean(ReceiptTimeDao.class);

	public static final String CACHE_PRODUCT = "product";
	public static final String CACHE_CLASSIFY_LIST = "classifyList";
	public static final String CACHE_CLASSIFY_ONE_LIST = "classifyOneList";
	public static final String CACHE_UNIT_LIST = "unitList";
	public static final String CACHE_SPEC_LIST = "specList";//采购单位
	public static final String CACHE_SUPPLIER_LIST = "supplierList";
	public static final String CACHE_PURCHASEMEMBER_LIST= "purchaseMemberList"; //采购人员
	public static final String CACHE_DELIVERYMEMBER_LIST= "deliveryMemberList"; //送货人员
	public static final String CACHE_TIMESLOT = "timeSlotList"; //收获时间段
	
	public static Product getProduct(){
		Product product = (Product)getCache(CACHE_PRODUCT);
		return product;
	}
	
	/**
	 * 获取当前商户的所有分类集合
	 * @return
	 */
	public static List<ProductClassify> getClassifyList(){
		@SuppressWarnings("unchecked")
		List<ProductClassify> sourcelist = (List<ProductClassify>)getCache(CACHE_CLASSIFY_LIST);
		List<ProductClassify> list = Lists.newArrayList();
		if (sourcelist == null){
			DetachedCriteria dc = productClassifyDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", ProductClassify.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.addOrder(Order.asc("sort"));
			sourcelist = productClassifyDao.find(dc);
			ProductClassify.sortList(list, sourcelist);
			putCache(CACHE_CLASSIFY_LIST, list);
		}else {
			list = sourcelist;
		}
		return list;
	}	
	
	/**
	 * 获取商品的一级分类列表
	 * @return
	 */
	public static List<ProductClassify> getClassifyOneList(){
		@SuppressWarnings("unchecked")
		List<ProductClassify> list = (List<ProductClassify>)getCache(CACHE_CLASSIFY_ONE_LIST);
		if (list == null){
			DetachedCriteria dc = productClassifyDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", ProductClassify.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.add(Restrictions.eq("level", "1"));
			dc.addOrder(Order.asc("sort"));
			list = productClassifyDao.find(dc);
			putCache(CACHE_CLASSIFY_ONE_LIST, list);
		}
		return list;
	}
	
	/**
	 * 获取二级分类，根据一级分类查询
	 * @param parentId
	 * @return
	 */
	public static List<ProductClassify> getClassifyTwoList(String parentId){
		if (StringUtils.isNotBlank(parentId)) {
			List<ProductClassify> list = Lists.newArrayList();
			DetachedCriteria dc = productClassifyDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", ProductClassify.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			if(StringUtils.isNotBlank(parentId)){
				dc.add(Restrictions.eq("parent.id", parentId));
			}
			dc.addOrder(Order.asc("sort"));
			list = productClassifyDao.find(dc);
			return list;
		}else {
			List<ProductClassify> rtnlist = Lists.newArrayList();
			List<ProductClassify> list = Lists.newArrayList();
			DetachedCriteria dc = productClassifyDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", ProductClassify.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.add(Restrictions.eq("level", "1"));
			dc.addOrder(Order.asc("sort"));
			list = productClassifyDao.find(dc);
			putCache(CACHE_CLASSIFY_ONE_LIST, list);
			for (ProductClassify parent : list) {
				for (ProductClassify child : parent.getChildList()) {
					child.setName(child.getName());
					rtnlist.add(child);
				}
			}
			return rtnlist;
		}
	}
	
	public static List<ProductClassify> getAllClassifyTwoList(){
		List<ProductClassify> rtnlist = Lists.newArrayList();
		List<ProductClassify> list = Lists.newArrayList();
		DetachedCriteria dc = productClassifyDao.createDetachedCriteria();
		dc.add(Restrictions.eq("delFlag", ProductClassify.DEL_FLAG_NORMAL));
		dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
		dc.add(Restrictions.eq("level", "1"));
		dc.addOrder(Order.asc("sort"));
		list = productClassifyDao.find(dc);
		putCache(CACHE_CLASSIFY_ONE_LIST, list);
		for (ProductClassify parent : list) {
			for (ProductClassify child : parent.getChildList()) {
				child.setName(parent.getName()+":"+child.getName());
				rtnlist.add(child);
			}
		}
		return rtnlist;
	}
	
	/**
	 * 获取当前商户所有的单位集合
	 * @return
	 */
	public static List<ProductUnit> getUnitList(String type){
		@SuppressWarnings("unchecked")
		List<ProductUnit> list = (List<ProductUnit>)getCache(CACHE_UNIT_LIST);
		if(type.equals("2")){
			list = (List<ProductUnit>)getCache(CACHE_SPEC_LIST);
		}
		if (list == null){
			DetachedCriteria dc = productUnitDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", ProductUnit.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.add(Restrictions.eq("type", type));
			dc.addOrder(Order.asc("sort"));
			list = productUnitDao.find(dc);
			if(type.equals("2")){
				putCache(CACHE_SPEC_LIST, list);
			}else{
				putCache(CACHE_UNIT_LIST, list);
			}
		}
		return list;
	}
	
	/**
	 * 获取当前商户所有送货员集合
	 * @return
	 */
	public static List<DeliveryMember> getDeliveryMemberList(int type){
		@SuppressWarnings("unchecked")
		List<DeliveryMember> list = (List<DeliveryMember>)getCache(type==DeliveryMember.TYPE_DELIVERY?CACHE_DELIVERYMEMBER_LIST:CACHE_PURCHASEMEMBER_LIST);
		if (list == null){
			DetachedCriteria dc = memberDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", DeliveryMember.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.add(Restrictions.eq("type", type));
			dc.addOrder(Order.asc("createDate"));
			list = memberDao.find(dc);
			putCache(type==DeliveryMember.TYPE_DELIVERY?CACHE_DELIVERYMEMBER_LIST:CACHE_PURCHASEMEMBER_LIST, list);
		}
		return list;
	}
	
	/**
	 * 获取当前商户供应商集合
	 * @return
	 */
	public static List<Supplier> getSupplierList(){
		@SuppressWarnings("unchecked")
		List<Supplier> list = (List<Supplier>)getCache(CACHE_SUPPLIER_LIST);
		if (list == null){
			DetachedCriteria dc = supplierDao.createDetachedCriteria();
			dc.add(Restrictions.eq("delFlag", Supplier.DEL_FLAG_NORMAL));
			dc.add(Restrictions.eq("merchant.id", MerchantUtils.getMerchant().getId()));
			dc.addOrder(Order.asc("createDate"));
			list = supplierDao.find(dc);
			putCache(CACHE_SUPPLIER_LIST, list);
		}
		return list;
	}
	
	public static Product getProductById(String id){
		if(StringUtils.isNotBlank(id)) {
			return productDao.get(id);
		} else {
			return null;
		}
	}
	
	// ============== User Cache ==============
	
	public static Object getCache(String key) {
		return getCache(key, null);
	}
	
	public static Object getCache(String key, Object defaultValue) {
		Object obj = getCacheMap().get(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
		getCacheMap().put(key, value);
	}

	public static void removeCache(String key) {
		getCacheMap().remove(key);
	}
	
	public static Map<String, Object> getCacheMap(){
		Map<String, Object> map = Maps.newHashMap();
		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal)subject.getPrincipal();
			return principal!=null?principal.getCacheMap():map;
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return map;
	}
	
	/**
	 * 获取当前商户供应商集合
	 * @return
	 */
	public static List<String> getTimeSlotList(){
		@SuppressWarnings("unchecked")
		List<String> list = (List<String>)getCache(CACHE_TIMESLOT);
		if (list == null){
			list = Lists.newArrayList();
			ReceiptTime receiptTime = new ReceiptTime();
			receiptTime = timeDao.findByMerchantId(MerchantUtils.getMerchant().getId());
			List<TimeSlot> timeList = receiptTime.getTimeSlots();
			for(TimeSlot timeSlot:timeList){
				String timeStr = timeSlot.getTimeText();
				if(timeStr.indexOf("次日")>-1 || timeStr.indexOf("后日")>-1 || timeStr.indexOf("当日")>-1){
					timeStr = timeStr.substring(2).trim();
				}
				if(list != null && list.contains(timeStr)){
					continue;
				}
				list.add(timeStr);
			}
			putCache(CACHE_TIMESLOT, list);
		}
		return list;
	}
	
}
